using ColorFillGame.Domain.Entities;
using ColorFillGame.Domain.Exceptions;
using ColorFillGame.Domain.Repositories;
using ColorFillGame.Domain.Services;
using MediatR;
using Microsoft.Extensions.Logging;

namespace ColorFillGame.Application.Commands.Game;

public class StartGameCommandHandler : IRequestHandler<StartGameCommand>
{
    private readonly IGameRepository _gameRepository;
    private readonly IPlayerRepository _playerRepository;
    private readonly IGameService _gameService;
    private readonly ILogger<StartGameCommandHandler> _logger;

    public StartGameCommandHandler(
        IGameRepository gameRepository,
        IPlayerRepository playerRepository,
        IGameService gameService,
        ILogger<StartGameCommandHandler> logger)
    {
        _gameRepository = gameRepository;
        _playerRepository = playerRepository;
        _gameService = gameService;
        _logger = logger;
    }

    public async Task Handle(StartGameCommand request, CancellationToken cancellationToken)
    {
        _logger.LogDebug("接收到开始游戏命令 - GameId: {GameId}, PlayerId: {PlayerId}", request.GameId, request.PlayerId);
        
        // 获取游戏
        var game = await _gameRepository.GetByIdAsync(request.GameId);
        _logger.LogDebug("获取游戏结果: {GameResult}", game == null ? "未找到游戏" : "找到游戏");
        
        if (game == null)
        {
            _logger.LogDebug("抛出GameNotFoundException - GameId: {GameId}", request.GameId);
            throw new GameNotFoundException(request.GameId);
        }

        // 检查游戏是否已经开始
        _logger.LogDebug("当前游戏状态: {GameStatus}", game.Status);
        if (game.Status == GameStatus.InProgress)
        {
            _logger.LogDebug("游戏已经开始，抛出GameAlreadyStartedException");
            throw new GameAlreadyStartedException(request.GameId);
        }

        // 获取玩家
        var player = await _playerRepository.GetByIdAsync(request.PlayerId);
        _logger.LogDebug("获取玩家结果: {PlayerResult}", player == null ? "未找到玩家" : "找到玩家");
        
        if (player == null)
        {
            _logger.LogDebug("抛出PlayerNotFoundException - PlayerId: {PlayerId}", request.PlayerId);
            throw new PlayerNotFoundException(request.PlayerId);
        }

        // 检查玩家是否属于该游戏
        _logger.LogDebug("玩家游戏ID: {PlayerGameId}, 请求游戏ID: {RequestGameId}", player.GameId, request.GameId);
        if (player.GameId != request.GameId)
        {
            _logger.LogDebug("玩家不属于该游戏，抛出DomainException");
            throw new DomainException("Player does not belong to this game.");
        }

        // 调试日志：显示当前游戏状态和玩家数量
        _logger.LogDebug("准备启动游戏 - GameId: {GameId}, 状态: {GameStatus}, 玩家数量: {PlayerCount}", 
            game.Id, game.Status, game.Players.Count);
        
        try
        {
            // 启动游戏
            _logger.LogDebug("调用_gameService.StartGame");
            _gameService.StartGame(game);
            _logger.LogDebug("游戏成功启动");
            _logger.LogDebug("游戏启动后状态: {GameStatus}", game.Status);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "启动游戏失败");
            throw;
        }
        
        _logger.LogDebug("调用_gameRepository.UpdateAsync");
        await _gameRepository.UpdateAsync(game);
        _logger.LogDebug("调用_gameRepository.SaveChangesAsync");
        await _gameRepository.SaveChangesAsync();
        
        _logger.LogDebug("游戏状态已保存 - 新状态: {GameStatus}, 开始时间: {StartedAt}", game.Status, game.StartedAt);
    }
}